﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DDD {

    /// <summary>
    /// ミップマップ階層の補間方法
    /// </summary>
    /// <remarks>
    /// <dic>LevelFilter</dic>はミップマップ階層間の補完方法を指定します。
    /// <dic>Base</dic>は常にLevel0を使用します。ミップマップを無効としたのに等しいです。
    /// <dic>Nearest</dic>は一番近いミップマップ階層レベルのみ使用します。
    /// <dic>Linear</dic>は２つのミップマップ階層を線形補完します。
    /// </remarks>
    public enum LevelFilter {
        /// <summary>常にLevel0を使用します(ミップマップ無効と同じ) </summary>
        Base,
        /// <summary>一番近いミップマップ階層のみを使用します</summary>
        Nearest,
        /// <summary>２つのミップマップ階層を利用して線形補完します</summary>
        Linear
    }

    /// <summary>
    /// 画像ピクセルの補間方法
    /// </summary>
    /// <remarks>
    /// 通常画面に表示する画像サイズ（幅ｘ高さ）とその元になる画像データのサイズ（幅ｘ高さ）は一致しません。
    /// <dic>ImageFilter</dic>はこの場合の画素間の補完方法を指定します。<dic>Nearest</dic>は一番高速ですが表示結果はプアです。
    /// <dic>Linear</dic>は高速で表示結果も良好です（デフォルト）。<dic>Anisotropic</dic>は異方性フィルタリングと言って
    /// 地面など大きいテクスチャー画像を浅い角度で平行に近い状態で見るときに有効です。
    /// <dic>Anisotropic</dic>はハードウェアによってはサポートされない事があります。
    /// </remarks>
    public enum ImageFilter {
        /// <summary>最近接ピクセル１点を画素値とする</summary>
        Nearest,
        /// <summary>近傍４ピクセルを線形補完した結果を画素値とします</summary>
        Linear,
        /// <summary>異方性フィルタリングを行った結果を画素値とします</summary>
        Anisotropic,
    }

    /// <summary>
    /// テクスチャータイプ
    /// </summary>
    public enum SamplerType {
        /// <summary>
        /// 2Dテクスチャー
        /// </summary>
        Texture2D,

        /// <summary>
        /// キューブテクスチャー
        /// </summary>
        TextureCube,

        /// <summary>
        /// デプステクスチャー
        /// </summary>
        TextureDepth,
    }

    /// <summary>
    /// <see cref="SamplerType"/>列挙型の拡張メソッドクラス
    /// </summary>
    public static class TextureTypeExtension {
        /// <summary>
        /// 使用する画像枚数を取得します
        /// </summary>
        /// <remarks>
        /// 2D画像で1枚、キューブ画像で6枚です。
        /// </remarks>
        /// <param name="type">テクスチャータイプ</param>
        /// <returns></returns>
        public static int ToImageCount (this SamplerType type) {
            switch (type) {
                case SamplerType.Texture2D: return 1;
                case SamplerType.TextureDepth: return 1;
                case SamplerType.TextureCube: return 6;
                default: return 0;
            }
        }
    }

    /// <summary>
    /// テクスチャー画像の繰り返し方法
    /// </summary>
    /// <remarks>
    /// <dic>TextureRepeatMode</dic>は範囲外のテクスチャー座標を指定された時のピクセル値の選択方法を規定します。
    /// テクスチャー座標は正規化され画像全体を(0,1]で表します。
    /// この範囲外を指定されたとき<dic>ClampSize</dic>は再も外側の１ピクセルを使用します。<dic>s = 0</dic>または<dic>s = 1.</dic>
    /// <dic>Repeat</dic>は画像が繰り返されているかのようにモジュロ演算を行いテクスチャー座標を(0,1]に折りたたみます。<dic>s = s % arrayLength.</dic>
    /// 範囲外を一定のカラーにする<dic>Constant</dic>相当の機能はありません。
    /// これはOpenGL ESが対応していないためで将来的にもサポートされません。
    /// MIRROR(反転)に関しては保留です。
    /// </remarks>
    public enum TextureWrapMode {
        /// <summary>最も外側のピクセルを使用します</summary>
        Clamp,
        /// <summary>画像を繰り返します</summary>
        Repeat
    }

    /// <summary>
    /// キーフレームの補間方法
    /// </summary>
    /// <remarks>
    /// <dic>InterpolationType</dic>はキーフレーム間の値の補完方法を指定します。</remarks>
    /// <dic>Step</dic>は前のフレームの値をそのまま使用します。
    /// <dic>Linear</dic>は前後のキーフレームの値を線形補間します。
    /// <dic>Spline</dic>は前後４フレームをスプライン補間します。
    /// <dic>Slerp</dic>はキーフレームがクオータニオンの場合のみ使用され前後のキーフレームの値を球面線形補間します。
    /// <dic>Squad</dic>はキーフレームがクオータニオンの場合のみ使用され前後４フレームをスプライン補間します。
    public enum InterpolationType {
        /// <summary>ステップ補完します。指定時刻より小さく、かつ一番近い時刻のキーフレームの値をそのまま使用します</summary>
        Step,
        /// <summary>前後のキーフレームの値を線形補間します。</summary>
        Linear,
        /// <summary>前後４つのキーフレームの値をスプライン補間します。計算式は今は省略。</summary>
        Spline,
        /// <summary>前後のキーフレームを球面線形補完します。クオータニオンの場合のみ使用可能です。</summary>
        Slerp,
        /// <summary>前後４つのキーフレームの値をスプライン補間します。クオータニオンの場合のみ使用可能です。</summary>
        SQuad
    }

    /// <summary>
    /// 画像ピクセルの内部形式
    /// </summary>
    /// <remarks>
    /// GPU内部で使用される画像ピクセル形式を指定します。
    /// CPU側で保存するデータの形式とは無関係です。
    /// 末尾の記号(i,ui,f)は、
    ///   なし - 固定少数
    ///    f   - 浮動小数
    ///    i   - 符号あり整数
    ///    ui  - 符号なし整数
    /// を示します。固定小数と浮動小数の２つを「小数型」、
    /// 符号あり整数と符号なし整数の２つを「整数型」と呼びます。
    /// 小数型はImage(float)で扱い、整数型はImage(byte),Image(short),Image(ushort),Image(int),Image(uint)で扱います。
    /// </remarks>
    public enum PixelFormat {
        R8,
        R8i,
        R8ui,
        R16,
        R16f,
        R16i,
        R16ui,
        R32f,
        R32i,
        R32ui,

        RG8,
        RG8i,
        RG8ui,
        RG16,
        RG16f,
        RG16i,
        RG16ui,
        RG32f,
        RG32i,
        RG32ui,

        RGB8,
        RGB8i,
        RGB8ui,
        RGB16,
        RGB16f,
        RGB16i,
        RGB16ui,
        RGB32f,
        RGB32i,
        RGB32ui,

        RGBA8,
        RGBA8i,
        RGBA8ui,
        RGBA16,
        RGBA16f,
        RGBA16i,
        RGBA16ui,
        RGBA32f,
        RGBA32i,
        RGBA32ui,

        RGB9e5,
        R11G11B10f,
        RGB10A2,
        RGB10A2ui,

        Depth
    }

    /// <summary>
    /// <see cref="PixelFormat"/>列挙型の拡張メソッドの定義
    /// </summary>
    public static class PixelFormatExtension {
        /// <summary>
        /// 1ピクセルあたりのコンポーネント数(GetComponent Per Pixel)
        /// </summary>
        /// <param name="format">ピクセルフォーマット</param>
        /// <returns>コンポーネント数</returns>
        public static int ToCpp (this PixelFormat format) {
            switch (format) {
                case PixelFormat.R8: return 1;
                case PixelFormat.R8i: return 1;
                case PixelFormat.R8ui: return 1;
                case PixelFormat.R16: return 1;
                case PixelFormat.R16f: return 1;
                case PixelFormat.R16i: return 1;
                case PixelFormat.R16ui: return 1;
                case PixelFormat.R32f: return 1;
                case PixelFormat.R32i: return 1;
                case PixelFormat.R32ui: return 1;

                case PixelFormat.RG8: return 2;
                case PixelFormat.RG8i: return 2;
                case PixelFormat.RG8ui: return 2;
                case PixelFormat.RG16: return 2;
                case PixelFormat.RG16f: return 2;
                case PixelFormat.RG16i: return 2;
                case PixelFormat.RG16ui: return 2;
                case PixelFormat.RG32f: return 2;
                case PixelFormat.RG32i: return 2;
                case PixelFormat.RG32ui: return 2;

                case PixelFormat.RGB8: return 3;
                case PixelFormat.RGB8i: return 3;
                case PixelFormat.RGB8ui: return 3;
                case PixelFormat.RGB16: return 3;
                case PixelFormat.RGB16f: return 3;
                case PixelFormat.RGB16i: return 3;
                case PixelFormat.RGB16ui: return 3;
                case PixelFormat.RGB32f: return 3;
                case PixelFormat.RGB32i: return 3;
                case PixelFormat.RGB32ui: return 3;

                case PixelFormat.RGBA8: return 4;
                case PixelFormat.RGBA8i: return 4;
                case PixelFormat.RGBA8ui: return 4;
                case PixelFormat.RGBA16: return 4;
                case PixelFormat.RGBA16f: return 4;
                case PixelFormat.RGBA16i: return 4;
                case PixelFormat.RGBA16ui: return 4;
                case PixelFormat.RGBA32f: return 4;
                case PixelFormat.RGBA32i: return 4;
                case PixelFormat.RGBA32ui: return 4;

                case PixelFormat.RGB9e5: return 3;
                case PixelFormat.R11G11B10f: return 3;
                case PixelFormat.RGB10A2: return 4;
                case PixelFormat.RGB10A2ui: return 4;

                case PixelFormat.Depth: return 1;
                default: throw new NotImplementedException ("Sorry");
            }
        }

        public static PixelFormatCategory ToCategory (this PixelFormat format) {
            switch (format) {
                case PixelFormat.R8: return PixelFormatCategory.Float;
                case PixelFormat.R8i: return PixelFormatCategory.Integer;
                case PixelFormat.R8ui: return PixelFormatCategory.Integer;
                case PixelFormat.R16: return PixelFormatCategory.Float;
                case PixelFormat.R16f: return PixelFormatCategory.Float;
                case PixelFormat.R16i: return PixelFormatCategory.Integer;
                case PixelFormat.R16ui: return PixelFormatCategory.Integer;
                case PixelFormat.R32f: return PixelFormatCategory.Float;
                case PixelFormat.R32i: return PixelFormatCategory.Integer;
                case PixelFormat.R32ui: return PixelFormatCategory.Integer;

                case PixelFormat.RG8: return PixelFormatCategory.Float;
                case PixelFormat.RG8i: return PixelFormatCategory.Integer;
                case PixelFormat.RG8ui: return PixelFormatCategory.Integer;
                case PixelFormat.RG16: return PixelFormatCategory.Float;
                case PixelFormat.RG16f: return PixelFormatCategory.Float;
                case PixelFormat.RG16i: return PixelFormatCategory.Integer;
                case PixelFormat.RG16ui: return PixelFormatCategory.Integer;
                case PixelFormat.RG32f: return PixelFormatCategory.Float;
                case PixelFormat.RG32i: return PixelFormatCategory.Integer;
                case PixelFormat.RG32ui: return PixelFormatCategory.Integer;

                case PixelFormat.RGB8: return PixelFormatCategory.Float;
                case PixelFormat.RGB8i: return PixelFormatCategory.Integer;
                case PixelFormat.RGB8ui: return PixelFormatCategory.Integer;
                case PixelFormat.RGB16: return PixelFormatCategory.Float;
                case PixelFormat.RGB16f: return PixelFormatCategory.Float;
                case PixelFormat.RGB16i: return PixelFormatCategory.Integer;
                case PixelFormat.RGB16ui: return PixelFormatCategory.Integer;
                case PixelFormat.RGB32f: return PixelFormatCategory.Float;
                case PixelFormat.RGB32i: return PixelFormatCategory.Integer;
                case PixelFormat.RGB32ui: return PixelFormatCategory.Integer;

                case PixelFormat.RGBA8: return PixelFormatCategory.Float;
                case PixelFormat.RGBA8i: return PixelFormatCategory.Integer;
                case PixelFormat.RGBA8ui: return PixelFormatCategory.Integer;
                case PixelFormat.RGBA16: return PixelFormatCategory.Float;
                case PixelFormat.RGBA16f: return PixelFormatCategory.Float;
                case PixelFormat.RGBA16i: return PixelFormatCategory.Integer;
                case PixelFormat.RGBA16ui: return PixelFormatCategory.Integer;
                case PixelFormat.RGBA32f: return PixelFormatCategory.Float;
                case PixelFormat.RGBA32i: return PixelFormatCategory.Integer;
                case PixelFormat.RGBA32ui: return PixelFormatCategory.Integer;

                case PixelFormat.RGB9e5: return PixelFormatCategory.Float;
                case PixelFormat.R11G11B10f: return PixelFormatCategory.Float;
                case PixelFormat.RGB10A2: return PixelFormatCategory.Float;
                case PixelFormat.RGB10A2ui: return PixelFormatCategory.Integer;

                case PixelFormat.Depth: return PixelFormatCategory.Float;
                default: throw new NotImplementedException ("Sorry");
            }
        }
    }

    public enum PixelFormatCategory {
        Integer,
        Float
    }

    public enum PixelType {
        Byte,
        SByte,
        Short,
        UShort,
        Int,
        UInt,
        Float
    }

    public static class PixelTypeExtensions {
        public static PixelType GetType<T> () {
            switch (typeof (T).Name) {
                case "Byte": return PixelType.Byte;
                case "SByte": return PixelType.SByte;
                case "Int16": return PixelType.Short;
                case "UInt16": return PixelType.UShort;
                case "Int32": return PixelType.Int;
                case "UInt32": return PixelType.UInt;
                case "Single": return PixelType.Float;
                default: throw new InvalidOperationException ("Unknown type, name=" + typeof (T).Name);
            }

        }
    }

    /// <summary>
    /// プリミティブの形式
    /// </summary>
    /// <remarks>
    /// 頂点と頂点を結びプリミティブ構成するインデックスの形式を指定します。
    /// <dic>Point</dic>は点を、<dic>Line</dic>は線を、<dic>Traingle</dic>は面を構成します。
    /// <dic>Vpp()</dic>で１プリミティブあたりの頂点数を取得可能です。
    /// 4角形やそれ以上の頂点数のポリゴンには対応しません。
    /// </remarks>
    public enum PrimitiveType {
        /// <summary>ポイントは1プリミティブ1頂点で3D空間上の一点を表現します。</summary>
        Point = 1,
        /// <summary>ラインは1プリミティブ2頂点で3D空間上の線分を表現をします。</summary>
        Line = 2,
        /// <summary>トライアングルは1プリミティブ3頂点で3D空間上の3角形を表現します。</summary>
        Triangle = 3
    }

    /// <summary>
    /// <see cref="PrimitiveType"/>列挙型の拡張メソッド定義
    /// </summary>
    public static class PrimitiveTypeExtensions {
        /// <summary>
        /// 1プリミティブあたりの頂点数
        /// </summary>
        public static int Cpp (this PrimitiveType type) {
            switch (type) {
                case  PrimitiveType.Point : return 1;
                case  PrimitiveType.Line : return 2;
                case  PrimitiveType.Triangle : return 3;
                default: throw new NotImplementedException("Sorry");
            }
        }
    }

    /// <summary>
    /// コンポーネント型
    /// </summary>
    public enum ComponentType {
        /// <summary>
        /// Byte型
        /// </summary>
        Byte,

        /// <summary>
        /// Signed Byte型
        /// </summary>
        SByte,

        /// <summary>
        /// Short型
        /// </summary>
        Short,

        /// <summary>
        /// Unsigned Short型
        /// </summary>
        UShort,

        /// <summary>
        /// Int型
        /// </summary>
        Int,

        /// <summary>
        /// Unsigned Int型
        /// </summary>
        UInt,

        /// <summary>
        /// 浮動小数点型
        /// </summary>
        Float
    }


    /// <summary>
    /// インデックス型
    /// </summary>
    /// <remarks>
    /// <see cref="IndexBuffer"/>で使用されるインデックスの型を1,2,4バイト型の中から選択します｡
    /// </remarks>
    public enum IndexType {
        /// <summary>1バイト型</summary>
        Byte,
        /// <summary>1バイト型</summary>
        SByte,
        /// <summary>2バイト型</summary>
        Short,
        /// <summary>2バイト型</summary>
        UShort,
        /// <summary>4バイト型</summary>
        Int,
        /// <summary>4バイト型</summary>
        UInt
    }





    /// <summary>
    /// カメラの投影方式
    /// </summary>
    /// <remarks>
    /// カメラの投影方式を指定します。
    /// <dic>Perspective</dic>は透視投影で近くのものが大きく、遠くのものが小さく見えます。
    /// <dic>Parallel</dic>は平行投影で近くのものも遠くのものも同じ大きさで見えます。
    /// <dic>Screen</dic>はスクリーン空間でピクセル数を指定して1:1で描画するのに使用します。
    /// <dic>Generic</dic>は任意のユーザー指定の投影行列を持つカメラを指定します
    /// </remarks>
    public enum ProjectionType {
        /// <summary>カメラを透視投影にします。近くのものは大きく、遠くのものは小さく見えます。</summary>
        Perspective,
        /// <summary>カメラを平行投影にします。近くのも遠くのものも同じ大きさに見えます。</summary>
        Parallel,
        /// <summary>カメラをスクリーン投影にします。スクリーン座標(ピクセル数)で指定して位置を指定できるようになります。主に2Dの描画で使用されます。</summary>
        Screen,
        /// <summary>カメラをジェネリックにします。ユーザー指定の任意の投影行列が指定可能です。</summary>
        Generic
    }

    /// <summary>
    /// シェーダーで宣言された変数型
    /// </summary>
    /// <remarks>
    /// シェーダーで宣言された変数の型です。
    /// UnknownはDDDで非対応の型を表します。
    /// </remarks>
    public enum ShaderVariableType {
        /// <summary>Bool型のスカラー</summary>summary>
        Bool,
        /// <summary>2要素のBool型のスカラー</summary>summary>
        BVec2,
        /// <summary>3要素のBool型のベクトル</summary>summary>
        BVec3,
        /// <summary>4要素のBool型のベクトル</summary>summary>
        BVec4,
        /// <summary>Float型のスカラー</summary>summary>
        Float,
        /// <summary>2要素のFloat型のベクトル</summary>summary>
        Vec2,
        /// <summary>3要素のFloat型のベクトル</summary>summary>
        Vec3,
        /// <summary>4要素のFloat型のベクトル</summary>summary>
        Vec4,
        /// <summary>Int型のスカラー</summary>summary>
        Int,
        /// <summary>2要素のInt型のベクトル</summary>summary>
        IVec2,
        /// <summary>3要素のInt型のベクトル</summary>summary>
        IVec3,
        /// <summary>4要素のInt型のベクトル</summary>summary>
        IVec4,
        /// <summary>Unsigned Int型のスカラー</summary>summary>
        UInt,
        /// <summary>2要素のUnsigned Int型のベクトル</summary>summary>
        UIVec2,
        /// <summary>3要素のUnsigned Int型のベクトル</summary>summary>
        UIVec3,
        /// <summary>4要素のUnsigned Int型のベクトル</summary>summary>
        UIVec4,
        /// <summary>2x2要素のFloat型の行列</summary>summary>
        Mat2x2,
        /// <summary>3x3要素のFloat型の行列</summary>summary>
        Mat3x3,
        /// <summary>3x4要素のFloat型の行列</summary>summary>
        Mat3x4,
        /// <summary>4x4要素のFloat型の行列</summary>summary>
        Mat4x4,
        /// <summary>2Dのサンプラー型(テクスチャー)</summary>summary>
        Sampler2D,
        /// <summary>Cubeのサンプラー型(テクスチャー)</summary>summary>
        SamplerCube,
        /// <summary>2Dシャドーのサンプラー型(テクスチャー)</summary>summary>
        Sampler2DShadow,
        /// <summary>DDDで認識しない型を指定された場合</summary>summary>
        Unknown,
    }

    /// <summary>
    /// 頂点データの使用目的(セマンティクス)
    /// </summary>
    /// <remarks>
    /// シェーダーに送られる頂点データはエンジン側から見るとただの数字の固まりであり特別意味のあるものではありません。
    /// しかしながら実装上一部の頂点データはエンジン側にセマンティクス(意味)を教える必要があります。
    /// <dic>Positions</dic>はその頂点データが3D空間上の位置情報であることを示します。
    /// <dic>Normals</dic>その頂点データが法線であることを示します。
    /// <dic>DontCare</dic>はそれ以外の特に知る必要がない頂点データを表すのに使用します。
    /// </remarks>
    public enum VertexSemantics {
        /// <summary>この頂点データが位置情報であることを示します</summary>
        Positions,
        /// <summary>この頂点データが法線情報であることを示します</summary>
        Normals,
        /// <summary>この頂点データがエンジン側にセマンティクスを知らせる必要がない事を示します</summary>
        DontCare
    }

    /// <summary>
    /// 繰り返しモード
    /// </summary>
    /// <remarks>
    /// 一連のキーフレームを再生した後の繰り返し方法を設定します。
    /// </remarks>
    public enum KeyframeRepeatMode {
        /// <summary>一回だけ</summary>
        Once,
        /// <summary>ループ</summary>
        Loop,
        /// <summary>加算ループ</summary>
        AdditiveLoop
    }

    /// <summary>
    /// カリングモード
    /// </summary>
    /// <remarks>
    /// カリングの方法を<paramref pred="None"/>,<paramref pred="Back"/>,<paramref pred="Front"/>の中からしています。
    /// <paramref name="None"/>はカリングせず両面描画します。
    /// <paramref name="Back"/>はバックフェースをカリングし表面だけ描画します。
    /// <paramref name="Front"/>はフロントフェースをカリングし裏面だけ描画します。
    /// <paramref name="FrontAndBack"/>はフロントとバックフェースの両方をカリングし描画しません
    /// ここで言う"表"と"裏"は<see cref="WindingMode"/>によって定義されます。
    /// </remarks>
    public enum CullingMode {
        /// <summary>
        /// カリングなし
        /// </summary>
        None,

        /// <summary>
        /// バックフェースカリング
        /// </summary>
        Back,

        /// <summary>
        /// フロントフェースカリング
        /// </summary>
        Front,

        /// <summary>
        /// フロント＆バックフェースカリング
        /// </summary>
        FrontAndBack
    }

    /// <summary>
    /// ワインディングモード
    /// </summary>
    /// <remarks>
    /// トライアングルの3頂点がどの順番に見えたときに"表"と見なすかを決めます。
    /// <paramref pred="CCW"/>は3頂点が反時計回りに見えたときにそのトライアングルは"表"を向いているとします。
    /// <paramref pred="CW"/>は3頂点が時計回りに見えたときにのトライアングルは"表"を向いているとします。
    /// 面の裏表はカリングの基準になります。
    /// 頂点Attributeにセットしたシェーディング法線とは関係のない概念です。
    /// </remarks>
    public enum WindingMode {
        /// <summary>
        /// 頂点が反時計回りに出現するとき表とみなします
        /// </summary>
        CCW,
        /// <summary>
        /// 頂点が時計回りに出現するとき裏と見なします
        /// </summary>
        CW
    }

    /// <summary>
    /// カラーブレンドファンクション
    /// </summary>
    /// <remarks>
    /// フラグメントをカラーバッファーに書き込むときのブレンド方式を決定します。
    /// </remarks>
    public enum ColorBlendFunction {
        /// <summary>
        /// 置き換え
        /// </summary>
        Replace,
        /// <summary>
        /// 加算合成
        /// </summary>
        Add,
        /// <summary>
        /// α合成
        /// </summary>
        Alpha,
        /// <summary>
        /// α合成(加算)
        /// </summary>
        AlphaAdd,
        /// <summary>
        /// 事前乗算済みのαを使用したα合成
        /// </summary>
        AlphaPremultiplied,
        /// <summary>
        /// α合成(減算)
        /// </summary>
        AlphaDarken,
        /// <summary>
        /// モジュレート
        /// </summary>
        Modulate,
        /// <summary>
        /// モジュレート(明るくする)
        /// </summary>
        ModulateX2,
        /// <summary>
        /// モジュレート(逆)
        /// </summary>
        ModulateInverse,
    }

    /// <summary>
    /// デプステスト比較関数
    /// </summary>
    /// <remarks>
    /// デプステストに使用される比較関数を定義します。
    /// </remarks>
    public enum DepthComparisonFunction {
        /// <summary>
        /// 常に通過
        /// </summary>
        Always,
        /// <summary>
        /// 等しいとき通過
        /// </summary>
        Equal,
        /// <summary>
        /// 等しくないとき通過
        /// </summary>
        NotEqual,
        /// <summary>
        /// 等しいか大きいとき通過
        /// </summary>
        GreaterEqual,
        /// <summary>
        /// 大きいとき通過
        /// </summary>
        Greater,
        /// <summary>
        /// 等しいか小さいとき通過
        /// </summary>
        LessEqual,
        /// <summary>
        /// 小さいとき通過
        /// </summary>
        Less,
        /// <summary>
        /// 常に通過しない
        /// </summary>
        Never,
    }

    /// <summary>
    /// キューブを構成する6面の方位指定
    /// </summary>
    /// <remarks>
    /// (メモ)そのまま配列のインデックスと使用している
    /// </remarks>
    public enum CubeFace {
        /// <summary>
        /// X軸方向負の面
        /// </summary>
        NegativeX = 0,

        /// <summary>
        /// X軸方向正の面
        /// </summary>
        PositiveX = 1,

        /// <summary>
        /// Y軸方向負の面
        /// </summary>
        NegativeY = 2,

        /// <summary>
        /// Y軸方向正の面
        /// </summary>
        PositiveY = 3,

        /// <summary>
        /// Z軸方向負の面
        /// </summary>
        NegativeZ = 4,

        /// <summary>
        /// Z軸方向正の面
        /// </summary>
        PositiveZ = 5,
    }


}
